package com.jh.fcsm.filter;

import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import com.jh.fcsm.common.RestApiResponse;
import com.jh.fcsm.constant.TokenConstants;
import com.jh.fcsm.util.security.RSAEncrypt;
import com.jh.fcsm.util.security.UUIDUtils;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.nio.charset.StandardCharsets;

@ControllerAdvice
public class ResponseFilter implements ResponseBodyAdvice<Object> {
    @Value("${spring.profiles.active}")
    private String active;

    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    /**
     * @Description: 该方法是拦截到返回值（即response中的数据），然后操作返回值，并返回
     *
     **/
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        if ("prod".equals(active)&&body instanceof RestApiResponse) {
            RestApiResponse result = (RestApiResponse) body;
            try {
                String bodyStr=Base64.encodeBase64String(result.toString().getBytes(StandardCharsets.UTF_8));
                String secret= UUIDUtils.generateShortUuid()+UUIDUtils.generateShortUuid();
                String sm4my=encryptBody(secret);
                return encrypt(bodyStr,secret)+"@"+sm4my;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return body;
    }

    private String encrypt(String value,String secret) throws Exception {
        SymmetricCrypto sm4 = SmUtil.sm4(secret.getBytes());
        return sm4.encryptBase64(value,StandardCharsets.UTF_8);//库加密结果
    }

    private String encryptBody(String body) throws Exception {
        // 在这里添加加密逻辑
        return RSAEncrypt.publicKeyEncrypt(body, TokenConstants.PUBLIC_KEY);
    }

}